﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Daphne.Controls
{
    /// <summary>
    /// Interaction logic for HoverButton.xaml
    /// </summary>
    public partial class HoverButton : UserControl
    {
        private const string _sImagePath = "AppData\\Pictures";
        private string _sAppPath;
        private string _sCompletePath;
        private BitmapSource _image;
        private BitmapSource _hoverImage;
        private bool _isHover = false;


        public HoverButton()
        {
            _sAppPath = System.IO.Path.GetDirectoryName(
                     Assembly.GetExecutingAssembly().Location);
            _sCompletePath = System.IO.Path.Combine(_sAppPath, _sImagePath);
            _image = _hoverImage = null;

            this.Loaded += HoverButton_Loaded;          

            InitializeComponent();
        }

        // Needed this hack to check command can execute due to the cooperation with WindowsFormHost controls
        void Command_CanExecuteChanged(object sender, EventArgs e)
        {
            RoutedUICommand cmd = uxButton.Command as RoutedUICommand;
            if (cmd == null)
                return;

            
            CommandBinding cmdBind = null;
            foreach (var wnd in Application.Current.Windows)
            {
                Window Wnd = wnd as Window;
                foreach (var binding in Wnd.CommandBindings)
                {
                    CommandBinding bind = binding as CommandBinding;
                    if (bind.Command == cmd)
                    {
                        cmdBind = bind;
                        break;
                    }
                }
            }
            if (cmdBind == null)
                return;

            FieldInfo fieldInfo = typeof(CommandBinding).GetField("CanExecute", BindingFlags.Instance | BindingFlags.NonPublic);
            CanExecuteRoutedEventHandler result = (CanExecuteRoutedEventHandler)fieldInfo.GetValue(cmdBind);                   
            if(result == null)
                return;

            CanExecuteRoutedEventArgs eArgs = (CanExecuteRoutedEventArgs)Activator.CreateInstance(typeof(CanExecuteRoutedEventArgs),
                                            BindingFlags.NonPublic |
                                            BindingFlags.Instance, null, 
                                            new object[2] {cmdBind.Command, 
                                                           null}, null);
            var re = EventManager.GetRoutedEvents().Where(r => r.Name == "CommandCheck").FirstOrDefault();
            if(re == null)
                re = EventManager.RegisterRoutedEvent("CommandCheck", RoutingStrategy.Bubble, typeof(RoutedEventHandler), this.GetType());
            eArgs.RoutedEvent = re;
            result(this, eArgs);



            if (eArgs.CanExecute == false)
            {
                uxButton.Opacity = 0.25;
            }
            else
            {
                uxButton.Opacity = 1;
            }
        }



        public void ReloadImages()
        {
            if (string.IsNullOrWhiteSpace(Image) == false)
            {
                _image = new BitmapImage(new Uri(System.IO.Path.Combine(_sCompletePath, Image)));
                //if (_isHover == false) 
                //    //this.DataContext = _image;
            }
            if (string.IsNullOrWhiteSpace(HoverImage) == false)
            {
                _hoverImage = new BitmapImage(new Uri(System.IO.Path.Combine(_sCompletePath, HoverImage)));
                //if (_isHover == true)
                //    this.DataContext = _hoverImage;
            }

            Images images = new Images();
            images.NormalImage = _image;
            images.HoverImage = _hoverImage;
            this.DataContext = images;

        }

        void HoverButton_Loaded(object sender, RoutedEventArgs e)
        {
            if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(
                new DependencyObject()) == true)
                return;

            // load images
            ReloadImages();

            double factor = this.ActualHeight / _image.Height;
            uxButton.Width = _image.Width * factor;
          

            uxButton.MouseEnter += uxButton_MouseEnter;
            uxButton.MouseLeave += uxButton_MouseLeave;

        }

        public new string ToolTip
        {
            get
            {
                return  (string)uxButton.ToolTip;
            }
            set
            {
                uxButton.ToolTip = value;
            }
        }

        public ICommand Command
        {
            get
            {
                return uxButton.Command;
            }
            set
            {
                if(uxButton.Command != null)
                    uxButton.Command.CanExecuteChanged -= Command_CanExecuteChanged;
                    
                uxButton.Command = value;
                uxButton.Command.CanExecuteChanged += Command_CanExecuteChanged;
            }
        }

        public string Image
        { get; set; }

        public string HoverImage
        { get; set; }

        

        protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
        {
            if (uxButton.Command != null)
                if (uxButton.Command.CanExecute(null) == false)
                    return;

            base.OnMouseLeftButtonUp(e);

            uxButton.Command.Execute(null);
        }

        protected void HandleOnMouseEnter() {
            if (uxButton.Command != null)
                if (uxButton.Command.CanExecute(null) == false)
                    return;

            _isHover = true;

            //if(_hoverImage != null)
            //    this.DataContext = _hoverImage;
        }

        protected void HandleOnMouseLeave()
        {
            //if (_image != null)
            //    this.DataContext = _image;

            _isHover = false;
        }


        protected override void OnMouseEnter(MouseEventArgs e)
        {
            HandleOnMouseEnter();
 	         base.OnMouseEnter(e);
        }

        protected override void OnMouseLeave(MouseEventArgs e)
        {
            HandleOnMouseLeave();
 	        base.OnMouseLeave(e);
        }

        void uxButton_MouseEnter(object sender, MouseEventArgs e)
        {
            HandleOnMouseEnter();
            this.UpdateLayout();
        }

        void uxButton_MouseLeave(object sender, MouseEventArgs e)
        {
            HandleOnMouseLeave();
            this.UpdateLayout();

        }

        private class Images {           
            public BitmapSource NormalImage
            { get; set; }

            public BitmapSource HoverImage
            { get; set; }
        }

    }
}
